// -----------------------------------------------------------------------
//  <copyright file="Resource.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2025 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2025/1/8 18:11</last-date>
// -----------------------------------------------------------------------

using System.Diagnostics;
using System.Text;

using DaprPlus.Authorization.Properties;
using DaprPlus.Filters;
using DaprPlus.Json;

using OSharp.Localized;


namespace DaprPlus.Authorization.Domain.Entities;

/// <summary>
/// 权限资源信息
/// </summary>
[DebuggerDisplay("{Code}-{ServiceName}-{Type}")]
[LocalizedDescription("String_Auth_Resource", typeof(ResAuthorization))]
public class Resource : HasBothEventEntityBase, IAggregateRoot, IResource, IEntityHash
{
    /// <summary>
    /// 获取或设置 资源名称
    /// </summary>
    public string Name { get; set; } = null!;

    /// <summary>
    /// 获取或设置 资源代码，资源唯一性的确定标识
    /// </summary>
    public string Code { get; set; } = null!;

    /// <summary>
    /// 获取或设置 资源描述
    /// </summary>
    public string? Description { get; set; }

    /// <summary>
    /// 获取或设置 服务名称
    /// </summary>
    public string ServiceName { get; set; } = null!;

    /// <summary>
    /// 获取或设置 资源类型
    /// </summary>
    public ResourceType Type { get; set; }

    /// <summary>
    /// 获取 资源访问类型
    /// </summary>
    public ResourceAccessType AccessType { get; set; }

    /// <summary>
    /// 获取或设置 访问类型是否已更改，如true，刷新资源时将忽略访问类型的变更
    /// </summary>
    public bool IsAccessTypeChanged { get; set; }

    /// <summary>
    /// 获取或设置 是否系统资源
    /// </summary>
    public bool IsSystem { get; set; }

    /// <summary>
    /// 是否锁定当前信息
    /// </summary>
    public bool IsLocked { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime CreatedTime { get; set; }

    /// <summary>
    /// 获取或设置 元数据JSON
    /// </summary>
    public string? MetadataJson { get; set; }

    /// <summary>
    /// 获取或设置 允许的操作列表JSON字符串
    /// </summary>
    public string? AllowedOperationsJson { get; set; }

    /// <summary>
    /// 获取或设置 角色资源信息集合
    /// </summary>
    public virtual List<RoleResource> RoleResources { get; set; } = new();

    public IDictionary<string, object> GetMetadata()
    {
        return string.IsNullOrEmpty(MetadataJson)
            ? []
            : MetadataJson.FromTextJson<Dictionary<string, object>>() ?? [];
    }

    /// <summary>
    /// 获取允许的操作列表
    /// </summary>
    public ResourceOperation[] GetAllowedOperations()
    {
        return string.IsNullOrEmpty(AllowedOperationsJson)
            ? []
            : AllowedOperationsJson.FromTextJson<ResourceOperation[]>() ?? [];
    }

    /// <summary>
    /// 获取 实体资源元数据
    /// </summary>
    /// <returns></returns>
    public EntityMetadata? GetEntityMetadata()
    {
        if (Type != ResourceType.Entity || string.IsNullOrEmpty(MetadataJson))
        {
            return null;
        }

        return MetadataJson.FromTextJson<EntityMetadata>();
    }

    public string GetHash()
    {
        var sb = new StringBuilder();
        var props = new object?[] { Name, Code, Description, ServiceName, Type,
            AccessType, IsAccessTypeChanged, IsLocked, MetadataJson, AllowedOperationsJson };
        foreach (var prop in props)
        {
            sb.Append(prop);
        }
        return sb.ToString().ToMd5Hash();
    }

    public RoleResource SetRoleResource(long roleId, string[] operations,
        IDictionary<string, Dictionary<DataOperation, FilterGroup>> filterGroups)
    {
        // 设置TargetEntityType并移除空的FilterGroup
        var filteredGroups = new Dictionary<string, Dictionary<DataOperation, FilterGroup>>();

        foreach (var entityDict in filterGroups)
        {
            var filteredEntityDict = new Dictionary<DataOperation, FilterGroup>();

            foreach (var operationDict in entityDict.Value)
            {
                var filterGroup = operationDict.Value;
                filterGroup.TargetEntityType = Code;

                // 只保留非空的FilterGroup
                if (!filterGroup.IsEmpty())
                {
                    filteredEntityDict[operationDict.Key] = filterGroup;
                }
            }

            // 只保留有FilterGroup的实体
            if (filteredEntityDict.Count > 0)
            {
                filteredGroups[entityDict.Key] = filteredEntityDict;
            }
        }

        var roleResource = RoleResources.FirstOrDefault(m => m.RoleId == roleId);
        if (roleResource == null)
        {
            roleResource = new RoleResource()
            {
                RoleId = roleId,
                ResourceId = Id,
                OperationsJson = operations.Length == 0 ? null : operations.ToTextJson(),
                FilterGroupsJson = filteredGroups.Count == 0 ? null : filteredGroups.ToTextJson()
            };
            roleResource.SetId();
            RoleResources.Add(roleResource);
        }
        else
        {
            roleResource.OperationsJson = operations.Length == 0 ? null : operations.ToTextJson();
            roleResource.FilterGroupsJson = filteredGroups.Count == 0 ? null : filteredGroups.ToTextJson();
        }
        return roleResource;
    }

    public RoleResource? RemoveRoleResource(long roleId)
    {
        var roleResource = RoleResources.FirstOrDefault(m => m.RoleId == roleId);
        if (roleResource == null)
        {
            return null;
        }
        RoleResources.Remove(roleResource);
        return roleResource;
    }

    public void ClearRoleResources()
    {
        RoleResources.Clear();
    }
}
